﻿using DiLe.Mes.Application.Common.Equipment;
using DiLe.Mes.Model.Common.Abnormal.Entity;
using DiLe.Mes.Model.Common.Equipment.Entity.Manage;
using Mapster;
using MiniExcelLibs;

namespace DiLe.Mes.Cloud.Controllers.Equipment.Info {
    /// <summary>
    /// 设备类型
    /// </summary>
    [ApiExplorerSettings(GroupName = ApiCloudGroupConst.EquipmentManage)]
    public class EquipmentTypeController : ApiBaseController {
        private readonly EquipmentManageClient _manageClient;
        private readonly IWebHostEnvironment _webHostEnvironment;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="equipmentManage"></param>
        public EquipmentTypeController(EquipmentManageClient equipmentManage, IWebHostEnvironment webHostEnvironment) {
            _manageClient = equipmentManage;
            _webHostEnvironment = webHostEnvironment;
        }

        /// <summary>
        /// 获取设备类型列表
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> GetEquipmentTypeList(QueryParameter parameter) {

            var whereExpression = Expressionable.Create<EquipmentTypeEntity>();

            if (!parameter.Keyword.IsNullOrEmpty()) {
                whereExpression.And(p => p.Name.Contains(parameter.Keyword));
            }
            if (parameter.Pagination == null) {
                var res = await _manageClient.GetEquipmentTypeListAsync(whereExpression.ToExpression());
                return Success(res);
            } else {
                var res = await _manageClient.GetEquipmentTypePageListAsync(whereExpression.ToExpression(), parameter.Pagination);
                return Success(res);
            }
        }
        /// <summary>
        /// 获取设备类型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetEquipmentType(long id) {
            var res = await _manageClient.GetEquipmentTypeAsync(id);
            if (res?.ParentId > 0) {
                var parent = await _manageClient.GetEquipmentTypeAsync(res.ParentId);
                res.ExtJson.Add("ParentName", parent?.Name);
            }
            return Success(res);
        }
        /// <summary>
        /// 保存设备类型
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> SaveEquipmentType(EquipmentTypeEntity entity) {
            var res = await _manageClient.SaveEquipmentTypeAsync(entity);
            return res ? Success() : Fail();
        }
        /// <summary>
        /// 删除设备类型
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> DeleteEquipmentType(List<long> ids) {
            var res = await _manageClient.DeleteEquipmentTypeAsync(ids);
            return res ? Success() : Fail();
        }
        /// <summary>
        /// 更新设备类型状态
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> UpdateEquipmentTypeStatus(CommomParameter parameter) {
            var res = await _manageClient.UpdateEquipmentTypeStatusAsync(parameter.Ids, parameter.Status);
            return res ? Success() : Fail();
        }
        /// <summary>
        /// 更新设备类型图片
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> UpdateEquipmentTypeFile(long typeId, string fileOid) {
            var m = await _manageClient.GetEquipmentTypeAsync(typeId);
            m.FileId = fileOid;
            var res = await _manageClient.SaveEquipmentTypeAsync(m);
            return res ? Success() : Fail();
        }
        #region 报警规则
        /// <summary>
        /// 上传报警报警规则
        /// </summary>
        /// <returns></returns>
        [HttpPost, DisableRequestSizeLimit]
        public async Task<ApiResult> UploadAbnormalAlarmInfo([FromForm] AbnormalUploadParameter parameter) {
            var file = parameter.Files?.FirstOrDefault();
            string rootPath = Path.Combine(_webHostEnvironment.ContentRootPath, $"wwwroot\\TemplateFiles");
            if (!Directory.Exists(rootPath)) {
                Directory.CreateDirectory(rootPath);
            }
            if (file == null || file?.Length <= 0) {
                return Fail();
            }
            var filePath = Path.Combine(rootPath, file!.FileName);
            using Stream fileStream = new FileStream(filePath, FileMode.Create);
            await file.CopyToAsync(fileStream);
            var sheetNames = MiniExcel.GetSheetNames(filePath);
            var list = new List<AbnormalAlarmRuleEntity>();
            foreach (var sheetName in sheetNames) {
                var rows = MiniExcel.Query(filePath, sheetName: sheetName).Cast<IDictionary<string, object>>();
                rows = rows.Skip(1).ToList();
                foreach (var row in rows) {
                    var m = new AbnormalAlarmRuleEntity();
                    m.EquipmentTypeId = parameter.TypeId;
                    if (sheetName != "Sheet1") {
                        m.AlarmName = $"{sheetName}-{row["A"]?.ToString() ?? ""}";
                    } else {
                        m.AlarmName = $"{row["A"]?.ToString() ?? ""}";
                    }
                    m.AlarmDescription = row["B"]?.ToString() ?? "";
                    m.AlarmLevel = row["C"]?.ToInt() ?? 0;
                    list.Add(m);
                }
            }
            _ = await _manageClient.InsertAbnormalAlarmRuleAsync(list);
            return Success(list);
        }
        /// <summary>
        /// 获取报警信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<List<AbnormalAlarmRuleEntity>>> GetAbnormalAlarmInfoByTypeId(long typeId) {
            var list = await _manageClient.GetAbnormalAlarmRuleListAsync(x => x.EquipmentTypeId == typeId);
            return Success(list);
        }
        /// <summary>
        /// 保存异常点位信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> SaveAbnormalAlarmPointPositionInfo(PointPositionInfo positionInfo) {
            var type = await _manageClient.GetEquipmentTypeAsync(positionInfo.TypeId);
            if (type != null) {
                type.FileId = positionInfo.FileId;
                _ = await _manageClient.SaveEquipmentTypeAsync(type);
            }
            var alarmRules = await _manageClient.GetAbnormalAlarmRuleListAsync(p => p.EquipmentTypeId == positionInfo.TypeId);
            //清理位置信息
            alarmRules.ForEach(x => x.Position = null);
            _ = await _manageClient.UpdateAbnormalAlarmRuleAsync(alarmRules);
            //更新位置信息
            var updates = new List<AbnormalAlarmRuleEntity>();
            foreach (var poin in positionInfo.PointArr) {
                var alarmRule = alarmRules.FirstOrDefault(x => x.Id == poin.Id);
                if (alarmRule == null) {
                    continue;
                }
                alarmRule.Position = poin.Position;
                updates.Add(alarmRule);
            }
            if (!updates.None()) {
                _ = await _manageClient.UpdateAbnormalAlarmRuleAsync(updates);
            }
            return Success("保存成功");
        }
        /// <summary>
        /// 获取异常点位信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult<PointPositionInfo>> GetAbnormalAlarmPointPositionInfo(long typeId) {
            PointPositionInfo info = new PointPositionInfo() {
                PointArr = []
            };
            var type = await _manageClient.GetEquipmentTypeAsync(typeId);
            if (type != null) {
                info.FileId = type.FileId ?? "";
                info.TypeId = type.Id;
            }
            var list = await _manageClient.GetAbnormalAlarmRuleListAsync(x => x.EquipmentTypeId == typeId);

            foreach (var poin in list) {
                if (poin.Position.IsNullOrEmpty()) {
                    continue;
                }
                info.PointArr.Add(poin);
            }
            return Success(info, "保存成功");
        }
        #endregion
    }
}
